/*
 * Classname IBrokerManagerService.java
 * 
 * Version Information
 * 
 * Date May 2, 2006
 *
 * Copyright (c) AmSoft Systems, 2006
 */
package net.amsoft.iservice.management.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import net.amsoft.iservice.management.util.IBrokerConstants;
import net.amsoft.iservice.management.util.IBrokerManagerHelpers;
import net.amsoft.iservice.management.util.ManagerHibernateUtil;
import net.amsoft.iservice.isso.hibernate.IBroker;
import net.amsoft.iservice.util.exception.IServiceException;
import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

/**
 * @author jyoti
 */
public class IBrokerManagerService {
    private static Logger logger = Logger
            .getLogger(IBrokerManagerService.class);

    /**
     * Sets the Broker Data for the psecified IBroker
     * 
     * @param sIBroker
     * @param oHashMap
     * @throws IServiceException
     */
    public static void setIBrokerData(String sIBroker, HashMap oHashMap,
            String sServiceType) throws IServiceException {
        // Get IBroker and set new data
        Session oSession = ManagerHibernateUtil.getSessionFactory(sServiceType)
                .openSession();
        Transaction oTransaction = oSession.beginTransaction();
        try {
            logger.warn("Fetching the IBroker in setIBrokerData()");
            if ((sServiceType.equals(IBrokerConstants
                    .getProperty(IBrokerConstants.SERVICE_ISSO)))) {
                IBroker oIBroker = null;
                oIBroker = IBrokerManagerHelpers.fetchIBrokerISSO(sIBroker,
                        oSession, oTransaction);
                oIBroker.setBrokerData(oHashMap);
                oIBroker.update();
                oSession.save(oIBroker);
                // Post new data to database
                logger.warn("setIBrokerData(): Updating database");
                commit(oSession, oTransaction);
            } else if ((sServiceType.equals(IBrokerConstants
                    .getProperty(IBrokerConstants.SERVICE_ICONTACT)))) {
                net.amsoft.iservice.icontact.hibernate.IBroker oIBroker = null;
                oIBroker = IBrokerManagerHelpers.fetchIBrokerIContact(sIBroker,
                        oSession, oTransaction);
                oIBroker.setBrokerData(oHashMap);
                oIBroker.update();
                oSession.save(oIBroker);
                // Post new data to database
                logger.warn("setIBrokerData(): Updating database");
                commit(oSession, oTransaction);
            } else if ((sServiceType.equals(IBrokerConstants
                    .getProperty(IBrokerConstants.SERVICE_ILINK)))) {
                net.amsoft.iservice.ilink.hibernate.IBroker oIBroker = null;
                oIBroker = IBrokerManagerHelpers.fetchIBrokerILink(sIBroker,
                        oSession, oTransaction);
                oIBroker.setBrokerData(oHashMap);
                oIBroker.update();
                oSession.save(oIBroker);
                // Post new data to database
                logger.warn("setIBrokerData(): Updating database");
                commit(oSession, oTransaction);
            }
        } catch (IServiceException e) {
            rollback(oSession, oTransaction);
            throw new IServiceException(e.getErrorCode(), false);
        }
    }

    /**
     * Gets the broker data for the specified IBroker
     * 
     * @param sIBroker
     * @return IBroker Data Map
     * @throws IServiceException
     */
    public static Map getIBrokerData(String sIBroker, String sServiceType)
            throws IServiceException {
        Map oDataMap = null;
        Session oSession = ManagerHibernateUtil.getSessionFactory(sServiceType)
                .openSession();
        Transaction oTransaction = oSession.beginTransaction();
        try {
            logger.warn("Fetching the IBroker in setIBrokerData()");
            if ((sServiceType.equals(IBrokerConstants
                    .getProperty(IBrokerConstants.SERVICE_ISSO)))) {
                IBroker oIBroker = null;
                oIBroker = IBrokerManagerHelpers.fetchIBrokerISSO(sIBroker,
                        oSession, oTransaction);
                oDataMap = oIBroker.getBrokerData();
                commit(oSession, oTransaction);
                return oDataMap;
            } else if ((sServiceType.equals(IBrokerConstants
                    .getProperty(IBrokerConstants.SERVICE_ICONTACT)))) {
                net.amsoft.iservice.icontact.hibernate.IBroker oIBroker = null;
                oIBroker = IBrokerManagerHelpers.fetchIBrokerIContact(sIBroker,
                        oSession, oTransaction);
                oDataMap = oIBroker.getBrokerData();
                commit(oSession, oTransaction);
                return oDataMap;
            } else if ((sServiceType.equals(IBrokerConstants
                    .getProperty(IBrokerConstants.SERVICE_ILINK)))) {
                net.amsoft.iservice.ilink.hibernate.IBroker oIBroker = null;
                oIBroker = IBrokerManagerHelpers.fetchIBrokerILink(sIBroker,
                        oSession, oTransaction);
                oDataMap = oIBroker.getBrokerData();
                commit(oSession, oTransaction);
                return oDataMap;
            }
        } catch (IServiceException e) {
            rollback(oSession, oTransaction);
            throw new IServiceException(e.getErrorCode(), false);
        }
        return oDataMap;
    }

    /**
     * Gets all the IBroker available for this service
     * 
     * @return ArrayList of all the IBrokers
     * @throws IServiceException
     */
    public static ArrayList getAllIBrokers(String sServiceType)
            throws IServiceException {
        logger.debug("getAllIBrokers() : Entry ");
        ArrayList oList = null;
        
        try
        {
            Session oSession = ManagerHibernateUtil.getSessionFactory(sServiceType)
                    .openSession();
            Transaction oTransaction = oSession.beginTransaction();
            logger.info("getAllIBrokers() : Fetching all the Ibrokers for "
                    + sServiceType);
            if ((sServiceType.equals(IBrokerConstants
                    .getProperty(IBrokerConstants.SERVICE_ISSO)))) {
                oList = (ArrayList) IBrokerManagerHelpers.fetchAllIBrokersISSO(
                        oSession, oTransaction);
            } else if ((sServiceType.equals(IBrokerConstants
                    .getProperty(IBrokerConstants.SERVICE_ICONTACT)))) {
                oList = (ArrayList) IBrokerManagerHelpers.fetchAllIBrokersIContact(
                        oSession, oTransaction);
            } else if ((sServiceType.equals(IBrokerConstants
                    .getProperty(IBrokerConstants.SERVICE_ILINK)))) {
                oList = (ArrayList) IBrokerManagerHelpers.fetchAllIBrokersILink(
                        oSession, oTransaction);
            }
            commit(oSession, oTransaction);
            logger.debug("getAllIBrokers() : Exiting After commit() ");
        }
        catch (HibernateException e)
        {
            logger.error("getAllIBrokers() : Exception -> " + e.getStackTrace());
        }
        
        return oList;
    }

    /**
     * Verifies if the user is ADMIN of the given service
     * 
     * @param sIBrokerName
     * @param sPrincipal
     * @param sServiceType
     * @return boolean
     * @throws IServiceException
     */
    public static boolean verifyAdmin(String sIBrokerName, String sPrincipal,
            String sServiceType) throws IServiceException {
        logger.debug("verifyAdmin() : Entry ");
        boolean bIsAdmin = false;
        Session oSession = ManagerHibernateUtil.getSessionFactory(sServiceType)
                .openSession();
        Transaction oTransaction = oSession.beginTransaction();
        logger.debug("verifyAdmin() : Verifying Admin for " + sServiceType);
        Map oMap = null;
        if ((sServiceType.equals(IBrokerConstants
                .getProperty(IBrokerConstants.SERVICE_ISSO))))
            oMap = IBrokerManagerHelpers.verifyIfIsAdminISSO(sIBrokerName,
                    sPrincipal, oSession, oTransaction);
        else if ((sServiceType.equals(IBrokerConstants
                .getProperty(IBrokerConstants.SERVICE_ILINK)))) {
            oMap = IBrokerManagerHelpers.verifyIfIsAdminILink(sIBrokerName,
                    sPrincipal, oSession, oTransaction);
        } else if ((sServiceType.equals(IBrokerConstants
                .getProperty(IBrokerConstants.SERVICE_ICONTACT)))) {
            oMap = IBrokerManagerHelpers.verifyIfIsAdminIContact(sIBrokerName,
                    sPrincipal, oSession, oTransaction);
        }
        logger.info("verifyAdmin() : Fetched Map " + oMap);
        if (oMap.containsKey(sPrincipal)) {
            int mapsize = oMap.size();
            Iterator keyValuePairs = oMap.entrySet().iterator();
            for (int i = 0; i < mapsize; i++) {
                Map.Entry entry = (Map.Entry) keyValuePairs.next();
                Object key = entry.getKey();
                String value = entry.getValue().toString();
                if (key.equals(sPrincipal)
                        && Integer.parseInt(value) == (IBrokerConstants.STATE_ACTIVE)) {
                    logger.info("verifyAdmin() : Found Admin " + sPrincipal);
                    bIsAdmin = true;
                    break;
                }
            }
        }
        commit(oSession, oTransaction);
        logger.debug("verifyAdmin() : Exit ");
        return bIsAdmin;
    }

    /**
     * Verifies if the synonym belongs to the princpal and the associated
     * principal state is active.
     * 
     * @param sGlobalINumber
     *            Global I Number of the synonym
     * @param sSynonym
     *            Synonym to be verified
     * @return true: If the syninym is subscrtibed to the service <BR>
     *         false: If the sybnonym is not subscribed to the service
     * @throws IServiceException
     *             Thrown if the global I Number does not exist
     */
    public static boolean verifySynonym(String sGlobalINumber, String sSynonym,
            String sIBroker, String sServiceType) throws IServiceException {
        logger.debug("verifySynonym() : Entry ");
        // Check if null data is not being passed
        if (sGlobalINumber == null || sSynonym == null) {
            throw new IServiceException(2028, false);
        }
        Session oSession = ManagerHibernateUtil.getSessionFactory(sServiceType)
                .openSession();
        Transaction oTransaction = oSession.beginTransaction();
        logger.info("verifySynonym() : Verifying Synonym for " + sServiceType);
        boolean bReturnValue = false;
        if ((sServiceType.equals(IBrokerConstants
                .getProperty(IBrokerConstants.SERVICE_ISSO)))) {
            try {
                bReturnValue = IBrokerManagerHelpers.verifySynonymISSO(
                        sGlobalINumber, sSynonym, sIBroker, oSession);
                logger.info("verifySynonym() : Found Synonym " + sSynonym
                        + " and  is active ");
            } catch (IServiceException ise) {
                logger
                        .error("verifySynonym() :  No matching active synonym Found ");
                rollback(oSession, oTransaction);
                throw ise;
            }
            commit(oSession, oTransaction);
            return bReturnValue;
        } else if ((sServiceType.equals(IBrokerConstants
                .getProperty(IBrokerConstants.SERVICE_ILINK)))) {
            try {
                bReturnValue = IBrokerManagerHelpers.verifySynonymILink(
                        sSynonym, sIBroker, oSession);
                logger.info("verifySynonym() : Found Synonym " + sSynonym
                        + " and  is active ");
            } catch (IServiceException ise) {
                logger
                        .error("verifySynonym() :  No matching active synonym Found ");
                rollback(oSession, oTransaction);
                throw ise;
            }
            commit(oSession, oTransaction);
            return bReturnValue;
        } else if ((sServiceType.equals(IBrokerConstants
                .getProperty(IBrokerConstants.SERVICE_ICONTACT)))) {
            try {
                bReturnValue = IBrokerManagerHelpers.verifySynonymIContact(
                        sGlobalINumber, sSynonym, sIBroker, oSession);
                logger.info("verifySynonym() : Found Synonym " + sSynonym
                        + " and  is active ");
            } catch (IServiceException ise) {
                logger
                        .error("verifySynonym() :  No matching active synonym Found ");
                rollback(oSession, oTransaction);
                throw ise;
            }
            commit(oSession, oTransaction);
            return bReturnValue;
        }
        return false;
    }

    private static void commit(Session oSession, Transaction oTransaction) {
        oTransaction.commit();
        oSession.clear();
        oSession.close();
        oSession = null;
        oTransaction = null;
    }

    /**
     * 
     */
    private static void rollback(Session oSession, Transaction oTransaction) {
        oTransaction.rollback();
        oSession.clear();
        oSession.close();
        oSession = null;
        oTransaction = null;
    }
}
